// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#include "optim/bundle_adjustment.h"
#include <iomanip>

namespace RVG {

void PrintSolverSummary(const ceres::Solver::Summary& summary) {
  LOG(INFO) << std::right << std::setw(16) << "Residuals : ";
  LOG(INFO) << std::left << summary.num_residuals_reduced << std::endl;

  LOG(INFO) << std::right << std::setw(16) << "Parameters : ";
  LOG(INFO) << std::left << summary.num_effective_parameters_reduced
            << std::endl;

  LOG(INFO) << std::right << std::setw(16) << "Iterations : ";
  LOG(INFO) << std::left
            << summary.num_successful_steps + summary.num_unsuccessful_steps
            << std::endl;

  LOG(INFO) << std::right << std::setw(16) << "Time : ";
  LOG(INFO) << std::left << summary.total_time_in_seconds << " [s]"
            << std::endl;

  LOG(INFO) << std::right << std::setw(16) << "Initial cost : ";
  LOG(INFO) << std::right << std::setprecision(6)
            << std::sqrt(summary.initial_cost / summary.num_residuals_reduced)
            << " [px]" << std::endl;

  LOG(INFO) << std::right << std::setw(16) << "Final cost : ";
  LOG(INFO) << std::right << std::setprecision(6)
            << std::sqrt(summary.final_cost / summary.num_residuals_reduced)
            << " [px]" << std::endl;

  LOG(INFO) << std::right << std::setw(16) << "Termination : ";

  std::string termination = "";

  switch (summary.termination_type) {
    case ceres::CONVERGENCE:
      termination = "Convergence";
      break;
    case ceres::NO_CONVERGENCE:
      termination = "No convergence";
      break;
    case ceres::FAILURE:
      termination = "Failure";
      break;
    case ceres::USER_SUCCESS:
      termination = "User success";
      break;
    case ceres::USER_FAILURE:
      termination = "User failure";
      break;
    default:
      termination = "Unknown";
      break;
  }

  LOG(INFO) << std::right << termination << std::endl;
  LOG(INFO) << std::endl;
}

}  // namespace colmap
